package cn.javacart.jfinal.php.render;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Map;

import php.runtime.Memory;
import php.runtime.env.CompileScope;
import php.runtime.env.Environment;
import php.runtime.reflection.ModuleEntity;

import com.jfinal.kit.LogKit;
import com.jfinal.render.ContentType;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;

/**
 * 通过PHP脚本渲染
 * 
 * @author farmer
 *
 */
public class PhpRender extends Render {
	
	private Map<Object, Memory> dataMap = null;
	
	public PhpRender(String view) {
		this.view = view;
	}
	
	/**
	 * 
	 * @param view
	 */
	public PhpRender(String view,Map<Object, Memory> dataMap) {
		this.view = view;
		this.dataMap = dataMap;
	}
	
	@Override
	public void render() {
		PhpEnvironment phpEnv = null;
		try {
			phpEnv = PhpEnvKit.getPhpEnv(); // 对象池获取对象
			Environment env = phpEnv.getEnv();
			CompileScope scope = phpEnv.getScope();
			synchronized (env) {
				env.getGlobals().clear();	//重要，使用之前清理变量
				ModuleEntity moduleEntity = phpEnv.getModuleEntity(view);
				if(dataMap != null){
					for(Map.Entry<Object, Memory> entry : dataMap.entrySet()){
						env.getGlobals().put(entry.getKey(), entry.getValue());
					}					
				}
				
				for (Enumeration<String> attrs=request.getAttributeNames(); attrs.hasMoreElements();) {
					String attrName = attrs.nextElement();
					Object attribute = request.getAttribute(attrName);
					if (attribute instanceof Memory) {
						env.getGlobals().put(attrName, (Memory)attribute);
					}
				}
				try {
					moduleEntity.includeNoThrow(env);
				} finally {
					scope.triggerProgramShutdown(env);
					try {
						env.doFinal();
					} catch (Throwable e) {
						LogKit.error("render异常！",e);
						throw new PhpRenderException("render异常！",e);
					}
				}
			}
			String text =phpEnv.getContent();
			PrintWriter writer = null;
			try {
				response.setHeader("Pragma", "no-cache");	// HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache
				response.setHeader("Cache-Control", "no-cache");
				response.setDateHeader("Expires", 0);
				response.setContentType(ContentType.HTML.toString());
				response.setCharacterEncoding(getEncoding());	// 与 contentType 分开设置
				writer = response.getWriter();
				writer.write(text);
				writer.flush();
			} catch (IOException e) {
				throw new RenderException(e);
			}
			finally {
				if (writer != null)
					writer.close();
			}
		} catch (Throwable e) {
			LogKit.error("获取PhpEnvironment异常",e);
			throw new RenderException("获取PhpEnvironment异常",e);
		} finally {
			PhpEnvKit.release(phpEnv);
		}
	}
	
}
